/*************************************************
 *	文件名称：queue.h
 *	文件说明：单链队列——队列的链式存储结构 的实现
 *	程序平台：
 *	文件作者：Jason <jasonsunsoft@163.com>
 *	文件时间：2014年9月22日 16:02
*************************************************/

#include "queue.h"

Status InitQueue(LinkQueue *Q)
//操作结果：构造一个队列Q
{
	Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
	if (!Q->front)
		exit(OVERFLOW);
	Q->front->next = NULL;
	return OK;
}

Status DestroyQueue(LinkQueue *Q)
//初始条件：队列Q存在且为空
//操作结果：销毁队列Q，Q不再存在
{
	while(Q->front)
	{
		Q->rear = Q->front->next;
		free(Q->front);
		Q->front = Q->rear;
	}
	return OK;
}

Status ClearQueue(LinkQueue *Q)
//初始条件：队列Q存在且不为空
//操作结果：将队列Q清空为空队列
{
	QueuePtr t;
	while(t != Q->rear)
	{
		t = Q->front->next;
		free(Q->front);
		Q->front = t;
	}
	Q->front->data = 0;
	return OK;
}

Status QueueEmpty(LinkQueue Q)
//初始条件：队列Q存在
//操作结果：若队列Q为空队列，则返回TRUE，否则返回FALSE
{
	if (Q.front == Q.rear)
		return TRUE;
	else
		return FALSE;
}

int QueueLength(LinkQueue Q)
//初始条件：队列Q存在
//操作结果：返回队列Q的元素个数，即为队列的长度
{
	int len = 0;
	QueuePtr t;

	t = Q.front;
	while(t != Q.rear)
	{
		len++;
		t = t->next;
	}

	return len;

}

Status GetHead(LinkQueue Q, QElemType *e)
//初始条件：队列Q存在
//操作结果：若队列不为空，则用e返回Q的队头元素，并返回OK；否则返回ERROR
{
	if (Q.front->next)
	{
		*e = Q.front->next->data;
		return OK;
	}
	return ERROR;
}

Status EnQueue(LinkQueue *Q, QElemType e)
//初始条件：队列Q存在
//操作结果：插入元素e为Q的新的队尾元素
{
	QueuePtr p;

	p = (QueuePtr) malloc(sizeof(QNode));
	if (!p)
		exit(OVERFLOW);
	p->data = e;
	p->next = NULL;
	Q->rear->next = p;
	Q->rear = p;
	return OK;
}

Status DeQueue(LinkQueue *Q, QElemType *e)
//初始条件：队列Q存在
//操作结果：若队列不为空，则删除Q的队头元素，用e返回其值，并返回OK；否则返回ERROR
{
	QueuePtr p;

	if (Q->front == Q->rear)
		return ERROR;
	p = Q->front->next;
	e = p->data;
	Q->front->next = p->next;
	if (Q->rear == p)
		Q->rear = Q->front;
	free(p);
	return OK;
}

Status QueueTraverse(LinkQueue Q, Status (*visit)(QElemType e))
//初始条件：队列Q存在且不为空
//操作结果：从队头到队尾依次对队列Q中每个元素调用函数visit()。一旦visit失败，则操作失败。
{
	QueuePtr temp;

	temp = Q.front->next;
	do
	{
		if (!visit(temp->data))
			return ERROR;
		temp = temp->next;
	}while(temp);

	return OK;
}
